#include "../include/test.h"

list *create_list(void) // 创建表
{
    list *plist = (list *)malloc(sizeof(list));
    if(plist == NULL){
        perror("malloc");
        return NULL;
    }
    memset(plist, 0, sizeof(list));

    int list_size = 0; // 初始化容量

    printf("请输入要创建的表的最大容量: ");
    scanf("%d", &list_size);

    plist->data = (data_type *)malloc(sizeof(data_type) * list_size); // 申请内存

    plist->size = list_size; // 赋值容量

    return plist;
}

int list_insert(list *plist, int index, data_type data) // 插入元素
{
    // 入参检测
    if(plist == NULL){ // 检测表是否存在
        return LIST_NOT_EXIST;
    }

    if(plist->count == plist->size){ // 检测容量是否已满
        return LIST_FULL;
    }

    if(index < -1 || index > plist->count){ // 检测索引是否合法，如果是 -1，则插入到表尾
        return INDEX_ERROR;
    }

    if(-1 == index){ // 插入到表尾       
        plist->data[plist->count] = data;
        plist->count++;
        return OK;
    }

    for(int i = plist->count; i > index; i--){ // 插入前移数据   
        plist->data[i] = plist->data[i-1];
    }

    // 插入到指定位置
    plist->data[index] = data;

    plist->count++;

    return OK;
}

int list_show(list *plist) // 显示表
{
    // 入参检测
    if(plist == NULL || plist->count == 0){
        return LIST_EMPTY;
    }

    for(int i = 0; i < plist->count; i++){ 
        printf("%d\t", plist->data[i]);
    }
    putchar(10);
    return OK;
}

int list_delete(list *plist, int index, data_type *data) // 删除元素
{
    if(plist == NULL){ // 表不存在
        return LIST_NOT_EXIST;
    }

    if(0 == plist->count){ // 表为空
        return LIST_EMPTY;
    }

    if(index < -1 || index > plist->count){ //  索引错误
        return INDEX_ERROR;
    }

    if(index == -1){ // 删除最后一个元素
        *data = plist->data[plist->count-1];
        plist->count--;
        return OK;
    }

    *data = plist->data[index]; // 保存要删除的元素
    for(int i = index; i < plist->count-1; i++){ // 移动元素
        plist->data[i] = plist->data[i+1]; // 元素前移
    }

    plist->count--; // 元素个数减1

    return OK;
}
/*
顺序表在删除元素后变得非常稀疏（即很多位置都是空的或未使用的），
但数组大小保持不变，那么这将导致内存使用的低效。
不过，这并不等同于内存泄露。内存泄露通常指的是程序无法再访问到的内存块，
但它们的空间没有被释放回操作系统。
内存泄露的潜在来源：内存泄露通常发生在动态分配的内存没有被正确释放时。
*/

int list_modify(list *plist, data_type old_data,  data_type new_data) // 修改元素
{
    if(plist == NULL){  // 表不存在
        return LIST_NOT_EXIST;
    }

    if(0 == plist->count){ // 表为空
        return LIST_EMPTY;
    }

    for(int i = 0; i < plist->count; i++){
        if(plist->data[i] == old_data){
            plist->data[i] = new_data;
            printf("修改成功！\n");
            return OK;
        }        
    }
    return DATA_NOT_EXIST; // 数据不存在
}


int list_search(list *plist, data_type data) // 查找元素
{
    if(plist == NULL){ // 表不存在
        return LIST_NOT_EXIST;
    }

    if(0 == plist->count){ // 表为空
        return LIST_EMPTY;
    }

    for(int i = 0; i < plist->count; i++){ // 遍历表
        if(plist->data[i] == data){
            printf("数据 %d 在表 %d 的位置\n", data, i);
            return OK;
        }
    }

    return DATA_NOT_EXIST; // 数据不存在
}

